


(function (window, $, undefined) {
    var defaultOpts = {beforeShow:noop, move:noop, change:noop, show:noop, hide:noop, color:false, flat:false, showInput:false, allowEmpty:false, showButtons:true, clickoutFiresChange:false, showInitial:false, showPalette:false, showPaletteOnly:false, showSelectionPalette:true, localStorageKey:false, appendTo:"body", maxSelectionSize:7, cancelText:"cancel", chooseText:"choose", preferredFormat:false, className:"", showAlpha:false, theme:"sp-light", palette:["fff", "000"], selectionPalette:[], disabled:false}, spectrums = [], IE = !!/msie/i.exec(window.navigator.userAgent), rgbaSupport = (function () {
        function contains(str, substr) {
            return !!~("" + str).indexOf(substr);
        }
        var elem = document.createElement("div");
        var style = elem.style;
        style.cssText = "background-color:rgba(0,0,0,.5)";
        return contains(style.backgroundColor, "rgba") || contains(style.backgroundColor, "hsla");
    })(), inputTypeColorSupport = (function () {
        var colorInput = $("<input type='color' value='!' />")[0];
        return colorInput.type === "color" && colorInput.value !== "!";
    })(), replaceInput = ["<div class='sp-replacer'>", "<div class='sp-preview'><div class='sp-preview-inner'></div></div>", "<div class='sp-dd'></div>", "</div>"].join(""), markup = (function () {
        var gradientFix = "";
        if (IE) {
            for (var i = 1; i <= 6; i++) {
                gradientFix += "<div class='sp-" + i + "'></div>";
            }
        }
        return ["<div class='sp-container sp-hidden'>", "<div class='sp-palette-container'>", "<div class='sp-palette sp-thumb sp-cf'></div>", "</div>", "<div class='sp-picker-container'>", "<div class='sp-top sp-cf'>", "<div class='sp-fill'></div>", "<div class='sp-top-inner'>", "<div class='sp-color'>", "<div class='sp-sat'>", "<div class='sp-val'>", "<div class='sp-dragger'></div>", "</div>", "</div>", "</div>", "<div class='sp-clear sp-clear-display' title='Clear Color Selection'>", "</div>", "<div class='sp-hue'>", "<div class='sp-slider'></div>", gradientFix, "</div>", "</div>", "<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>", "</div>", "<div class='sp-input-container sp-cf'>", "<input class='sp-input' type='text' spellcheck='false'  />", "</div>", "<div class='sp-initial sp-thumb sp-cf'></div>", "<div class='sp-button-container sp-cf'>", "<a class='sp-cancel' href='#'></a>", "<button class='sp-choose'></button>", "</div>", "</div>", "</div>"].join("");
    })();
    function paletteTemplate(p, color, className) {
        var html = [];
        for (var i = 0; i < p.length; i++) {
            var current = p[i];
            if (current) {
                var tiny = tinycolor(current);
                var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
                c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
                var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
                html.push("<span title=\"" + tiny.toRgbString() + "\" data-color=\"" + tiny.toRgbString() + "\" class=\"" + c + "\"><span class=\"sp-thumb-inner\" style=\"" + swatchStyle + ";\" /></span>");
            } else {
                var cls = "sp-clear-display";
                html.push("<span title=\"No Color Selected\" data-color=\"\" style=\"background-color:transparent;\" class=\"" + cls + "\"></span>");
            }
        }
        return "<div class='sp-cf " + className + "'>" + html.join("") + "</div>";
    }
    function hideAll() {
        for (var i = 0; i < spectrums.length; i++) {
            if (spectrums[i]) {
                spectrums[i].hide();
            }
        }
    }
    function instanceOptions(o, callbackContext) {
        var opts = $.extend({}, defaultOpts, o);
        opts.callbacks = {"move":bind(opts.move, callbackContext), "change":bind(opts.change, callbackContext), "show":bind(opts.show, callbackContext), "hide":bind(opts.hide, callbackContext), "beforeShow":bind(opts.beforeShow, callbackContext)};
        return opts;
    }
    function spectrum(element, o) {
        var opts = instanceOptions(o, element), flat = opts.flat, showSelectionPalette = opts.showSelectionPalette, localStorageKey = opts.localStorageKey, theme = opts.theme, callbacks = opts.callbacks, resize = throttle(reflow, 10), visible = false, dragWidth = 0, dragHeight = 0, dragHelperHeight = 0, slideHeight = 0, slideWidth = 0, alphaWidth = 0, alphaSlideHelperWidth = 0, slideHelperHeight = 0, currentHue = 0, currentSaturation = 0, currentValue = 0, currentAlpha = 1, palette = opts.palette.slice(0), paletteArray = $.isArray(palette[0]) ? palette : [palette], selectionPalette = opts.selectionPalette.slice(0), maxSelectionSize = opts.maxSelectionSize, draggingClass = "sp-dragging", shiftMovementDirection = null;
        var doc = element.ownerDocument, body = doc.body, boundElement = $(element), disabled = false, container = $(markup, doc).addClass(theme), dragger = container.find(".sp-color"), dragHelper = container.find(".sp-dragger"), slider = container.find(".sp-hue"), slideHelper = container.find(".sp-slider"), alphaSliderInner = container.find(".sp-alpha-inner"), alphaSlider = container.find(".sp-alpha"), alphaSlideHelper = container.find(".sp-alpha-handle"), textInput = container.find(".sp-input"), paletteContainer = container.find(".sp-palette"), initialColorContainer = container.find(".sp-initial"), cancelButton = container.find(".sp-cancel"), clearButton = container.find(".sp-clear"), chooseButton = container.find(".sp-choose"), isInput = boundElement.is("input"), isInputTypeColor = isInput && inputTypeColorSupport && boundElement.attr("type") === "color", shouldReplace = isInput && !flat, replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className) : $([]), offsetElement = (shouldReplace) ? replacer : boundElement, previewElement = replacer.find(".sp-preview-inner"), initialColor = opts.color || (isInput && boundElement.val()), colorOnShow = false, preferredFormat = opts.preferredFormat, currentPreferredFormat = preferredFormat, clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange, isEmpty = !initialColor, allowEmpty = opts.allowEmpty && !isInputTypeColor;
        function applyOptions() {
            if (opts.showPaletteOnly) {
                opts.showPalette = true;
            }
            container.toggleClass("sp-flat", flat);
            container.toggleClass("sp-input-disabled", !opts.showInput);
            container.toggleClass("sp-alpha-enabled", opts.showAlpha);
            container.toggleClass("sp-clear-enabled", allowEmpty);
            container.toggleClass("sp-buttons-disabled", !opts.showButtons);
            container.toggleClass("sp-palette-disabled", !opts.showPalette);
            container.toggleClass("sp-palette-only", opts.showPaletteOnly);
            container.toggleClass("sp-initial-disabled", !opts.showInitial);
            container.addClass(opts.className);
            reflow();
        }
        function initialize() {
            if (IE) {
                container.find("*:not(input)").attr("unselectable", "on");
            }
            applyOptions();
            if (shouldReplace) {
                boundElement.after(replacer).hide();
            }
            if (!allowEmpty) {
                clearButton.hide();
            }
            if (flat) {
                boundElement.after(container).hide();
            } else {
                var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
                if (appendTo.length !== 1) {
                    appendTo = $("body");
                }
                appendTo.append(container);
            }
            if (localStorageKey && window.localStorage) {
                try {
                    var oldPalette = window.localStorage[localStorageKey].split(",#");
                    if (oldPalette.length > 1) {
                        delete window.localStorage[localStorageKey];
                        $.each(oldPalette, function (i, c) {
                            addColorToSelectionPalette(c);
                        });
                    }
                }
                catch (e) {
                }
                try {
                    selectionPalette = window.localStorage[localStorageKey].split(";");
                }
                catch (e) {
                }
            }
            offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
                if (!disabled) {
                    toggle();
                }
                e.stopPropagation();
                if (!$(e.target).is("input")) {
                    e.preventDefault();
                }
            });
            if (boundElement.is(":disabled") || (opts.disabled === true)) {
                disable();
            }
            container.click(stopPropagation);
            textInput.change(setFromTextInput);
            textInput.bind("paste", function () {
                setTimeout(setFromTextInput, 1);
            });
            textInput.keydown(function (e) {
                if (e.keyCode == 13) {
                    setFromTextInput();
                }
            });
            cancelButton.text(opts.cancelText);
            cancelButton.bind("click.spectrum", function (e) {
                e.stopPropagation();
                e.preventDefault();
                hide("cancel");
            });
            clearButton.bind("click.spectrum", function (e) {
                e.stopPropagation();
                e.preventDefault();
                isEmpty = true;
                move();
                if (flat) {
                    updateOriginalInput(true);
                }
            });
            chooseButton.text(opts.chooseText);
            chooseButton.bind("click.spectrum", function (e) {
                e.stopPropagation();
                e.preventDefault();
                if (isValid()) {
                    updateOriginalInput(true);
                    hide();
                }
            });
            draggable(alphaSlider, function (dragX, dragY, e) {
                currentAlpha = (dragX / alphaWidth);
                isEmpty = false;
                if (e.shiftKey) {
                    currentAlpha = Math.round(currentAlpha * 10) / 10;
                }
                move();
            });
            draggable(slider, function (dragX, dragY) {
                currentHue = parseFloat(dragY / slideHeight);
                isEmpty = false;
                move();
            }, dragStart, dragStop);
            draggable(dragger, function (dragX, dragY, e) {
                if (!e.shiftKey) {
                    shiftMovementDirection = null;
                } else {
                    if (!shiftMovementDirection) {
                        var oldDragX = currentSaturation * dragWidth;
                        var oldDragY = dragHeight - (currentValue * dragHeight);
                        var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
                        shiftMovementDirection = furtherFromX ? "x" : "y";
                    }
                }
                var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
                var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
                if (setSaturation) {
                    currentSaturation = parseFloat(dragX / dragWidth);
                }
                if (setValue) {
                    currentValue = parseFloat((dragHeight - dragY) / dragHeight);
                }
                isEmpty = false;
                move();
            }, dragStart, dragStop);
            if (!!initialColor) {
                set(initialColor);
                updateUI();
                currentPreferredFormat = preferredFormat || tinycolor(initialColor).format;
                addColorToSelectionPalette(initialColor);
            } else {
                updateUI();
            }
            if (flat) {
                show();
            }
            function palletElementClick(e) {
                if (e.data && e.data.ignore) {
                    set($(this).data("color"));
                    move();
                } else {
                    set($(this).data("color"));
                    updateOriginalInput(true);
                    move();
                    hide();
                }
                return false;
            }
            var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
            paletteContainer.delegate(".sp-thumb-el", paletteEvent, palletElementClick);
            initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, {ignore:true}, palletElementClick);
        }
        function addColorToSelectionPalette(color) {
            if (showSelectionPalette) {
                var colorRgb = tinycolor(color).toRgbString();
                if ($.inArray(colorRgb, selectionPalette) === -1) {
                    selectionPalette.push(colorRgb);
                    while (selectionPalette.length > maxSelectionSize) {
                        selectionPalette.shift();
                    }
                }
                if (localStorageKey && window.localStorage) {
                    try {
                        window.localStorage[localStorageKey] = selectionPalette.join(";");
                    }
                    catch (e) {
                    }
                }
            }
        }
        function getUniqueSelectionPalette() {
            var unique = [];
            var p = selectionPalette;
            var paletteLookup = {};
            var rgb;
            if (opts.showPalette) {
                for (var i = 0; i < paletteArray.length; i++) {
                    for (var j = 0; j < paletteArray[i].length; j++) {
                        rgb = tinycolor(paletteArray[i][j]).toRgbString();
                        paletteLookup[rgb] = true;
                    }
                }
                for (i = 0; i < p.length; i++) {
                    rgb = tinycolor(p[i]).toRgbString();
                    if (!paletteLookup.hasOwnProperty(rgb)) {
                        unique.push(p[i]);
                        paletteLookup[rgb] = true;
                    }
                }
            }
            return unique.reverse().slice(0, opts.maxSelectionSize);
        }
        function drawPalette() {
            var currentColor = get();
            var html = $.map(paletteArray, function (palette, i) {
                return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i);
            });
            if (selectionPalette) {
                html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection"));
            }
            paletteContainer.html(html.join(""));
        }
        function drawInitial() {
            if (opts.showInitial) {
                var initial = colorOnShow;
                var current = get();
                initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial"));
            }
        }
        function dragStart() {
            if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
                reflow();
            }
            container.addClass(draggingClass);
            shiftMovementDirection = null;
        }
        function dragStop() {
            container.removeClass(draggingClass);
        }
        function setFromTextInput() {
            var value = textInput.val();
            if ((value === null || value === "") && allowEmpty) {
                set(null);
            } else {
                var tiny = tinycolor(value);
                if (tiny.ok) {
                    set(tiny);
                } else {
                    textInput.addClass("sp-validation-error");
                }
            }
        }
        function toggle() {
            if (visible) {
                hide();
            } else {
                show();
            }
        }
        function show() {
            var event = $.Event("beforeShow.spectrum");
            if (visible) {
                reflow();
                return;
            }
            boundElement.trigger(event, [get()]);
            if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
                return;
            }
            hideAll();
            visible = true;
            $(doc).bind("click.spectrum", hide);
            $(window).bind("resize.spectrum", resize);
            replacer.addClass("sp-active");
            container.removeClass("sp-hidden");
            if (opts.showPalette) {
                drawPalette();
            }
            reflow();
            updateUI();
            colorOnShow = get();
            drawInitial();
            callbacks.show(colorOnShow);
            boundElement.trigger("show.spectrum", [colorOnShow]);
        }
        function hide(e) {
            if (e && e.type == "click" && e.button == 2) {
                return;
            }
            if (!visible || flat) {
                return;
            }
            visible = false;
            $(doc).unbind("click.spectrum", hide);
            $(window).unbind("resize.spectrum", resize);
            replacer.removeClass("sp-active");
            container.addClass("sp-hidden");
            var colorHasChanged = !tinycolor.equals(get(), colorOnShow);
            if (colorHasChanged) {
                if (clickoutFiresChange && e !== "cancel") {
                    updateOriginalInput(true);
                } else {
                    revert();
                }
            }
            callbacks.hide(get());
            boundElement.trigger("hide.spectrum", [get()]);
        }
        function revert() {
            set(colorOnShow, true);
        }
        function set(color, ignoreFormatChange) {
            if (tinycolor.equals(color, get())) {
                return;
            }
            var newColor;
            if (!color && allowEmpty) {
                isEmpty = true;
            } else {
                isEmpty = false;
                newColor = tinycolor(color);
                var newHsv = newColor.toHsv();
                currentHue = (newHsv.h % 360) / 360;
                currentSaturation = newHsv.s;
                currentValue = newHsv.v;
                currentAlpha = newHsv.a;
            }
            updateUI();
            if (newColor && newColor.ok && !ignoreFormatChange) {
                currentPreferredFormat = preferredFormat || newColor.format;
            }
        }
        function get(opts) {
            opts = opts || {};
            if (allowEmpty && isEmpty) {
                return null;
            }
            return tinycolor.fromRatio({h:currentHue, s:currentSaturation, v:currentValue, a:Math.round(currentAlpha * 100) / 100}, {format:opts.format || currentPreferredFormat});
        }
        function isValid() {
            return !textInput.hasClass("sp-validation-error");
        }
        function move() {
            updateUI();
            callbacks.move(get());
            boundElement.trigger("move.spectrum", [get()]);
        }
        function updateUI() {
            textInput.removeClass("sp-validation-error");
            updateHelperLocations();
            var flatColor = tinycolor.fromRatio({h:currentHue, s:1, v:1});
            dragger.css("background-color", flatColor.toHexString());
            var format = currentPreferredFormat;
            if (currentAlpha < 1) {
                if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
                    format = "rgb";
                }
            }
            var realColor = get({format:format}), displayColor = "";
            previewElement.removeClass("sp-clear-display");
            previewElement.css("background-color", "transparent");
            if (!realColor && allowEmpty) {
                previewElement.addClass("sp-clear-display");
            } else {
                var realHex = realColor.toHexString(), realRgb = realColor.toRgbString();
                if (rgbaSupport || realColor.alpha === 1) {
                    previewElement.css("background-color", realRgb);
                } else {
                    previewElement.css("background-color", "transparent");
                    previewElement.css("filter", realColor.toFilter());
                }
                if (opts.showAlpha) {
                    var rgb = realColor.toRgb();
                    rgb.a = 0;
                    var realAlpha = tinycolor(rgb).toRgbString();
                    var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
                    if (IE) {
                        alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({gradientType:1}, realHex));
                    } else {
                        alphaSliderInner.css("background", "-webkit-" + gradient);
                        alphaSliderInner.css("background", "-moz-" + gradient);
                        alphaSliderInner.css("background", "-ms-" + gradient);
                        alphaSliderInner.css("background", gradient);
                    }
                }
                displayColor = realColor.toString(format);
            }
            if (opts.showInput) {
                textInput.val(displayColor);
            }
            if (opts.showPalette) {
                drawPalette();
            }
            drawInitial();
        }
        function updateHelperLocations() {
            var s = currentSaturation;
            var v = currentValue;
            if (allowEmpty && isEmpty) {
                alphaSlideHelper.hide();
                slideHelper.hide();
                dragHelper.hide();
            } else {
                alphaSlideHelper.show();
                slideHelper.show();
                dragHelper.show();
                var dragX = s * dragWidth;
                var dragY = dragHeight - (v * dragHeight);
                dragX = Math.max(-dragHelperHeight, Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight));
                dragY = Math.max(-dragHelperHeight, Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight));
                dragHelper.css({"top":dragY, "left":dragX});
                var alphaX = currentAlpha * alphaWidth;
                alphaSlideHelper.css({"left":alphaX - (alphaSlideHelperWidth / 2)});
                var slideY = (currentHue) * slideHeight;
                slideHelper.css({"top":slideY - slideHelperHeight});
            }
        }
        function updateOriginalInput(fireCallback) {
            var color = get(), displayColor = "", hasChanged = !tinycolor.equals(color, colorOnShow);
            if (color) {
                displayColor = color.toString(currentPreferredFormat);
                addColorToSelectionPalette(color);
            }
            if (isInput) {
                boundElement.val(displayColor);
            }
            colorOnShow = color;
            if (fireCallback && hasChanged) {
                callbacks.change(color);
                boundElement.trigger("change", [color]);
            }
        }
        function reflow() {
            dragWidth = dragger.width();
            dragHeight = dragger.height();
            dragHelperHeight = dragHelper.height();
            slideWidth = slider.width();
            slideHeight = slider.height();
            slideHelperHeight = slideHelper.height();
            alphaWidth = alphaSlider.width();
            alphaSlideHelperWidth = alphaSlideHelper.width();
            if (!flat) {
                container.css("position", "absolute");
                container.offset(getOffset(container, offsetElement));
            }
            updateHelperLocations();
        }
        function destroy() {
            boundElement.show();
            offsetElement.unbind("click.spectrum touchstart.spectrum");
            container.remove();
            replacer.remove();
            spectrums[spect.id] = null;
        }
        function option(optionName, optionValue) {
            if (optionName === undefined) {
                return $.extend({}, opts);
            }
            if (optionValue === undefined) {
                return opts[optionName];
            }
            opts[optionName] = optionValue;
            applyOptions();
        }
        function enable() {
            disabled = false;
            boundElement.attr("disabled", false);
            offsetElement.removeClass("sp-disabled");
        }
        function disable() {
            hide();
            disabled = true;
            boundElement.attr("disabled", true);
            offsetElement.addClass("sp-disabled");
        }
        initialize();
        var spect = {show:show, hide:hide, toggle:toggle, reflow:reflow, option:option, enable:enable, disable:disable, set:function (c) {
            set(c);
            updateOriginalInput();
        }, get:get, destroy:destroy, container:container};
        spect.id = spectrums.push(spect) - 1;
        return spect;
    }
    function getOffset(picker, input) {
        var extraY = 0;
        var dpWidth = picker.outerWidth();
        var dpHeight = picker.outerHeight();
        var inputHeight = input.outerHeight();
        var doc = picker[0].ownerDocument;
        var docElem = doc.documentElement;
        var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
        var viewHeight = docElem.clientHeight + $(doc).scrollTop();
        var offset = input.offset();
        offset.top += inputHeight;
        offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0);
        offset.top -= Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(dpHeight + inputHeight - extraY) : extraY));
        return offset;
    }
    function noop() {
    }
    function stopPropagation(e) {
        e.stopPropagation();
    }
    function bind(func, obj) {
        var slice = Array.prototype.slice;
        var args = slice.call(arguments, 2);
        return function () {
            return func.apply(obj, args.concat(slice.call(arguments)));
        };
    }
    function draggable(element, onmove, onstart, onstop) {
        onmove = onmove || function () {
        };
        onstart = onstart || function () {
        };
        onstop = onstop || function () {
        };
        var doc = element.ownerDocument || document;
        var dragging = false;
        var offset = {};
        var maxHeight = 0;
        var maxWidth = 0;
        var hasTouch = ("ontouchstart" in window);
        var duringDragEvents = {};
        duringDragEvents["selectstart"] = prevent;
        duringDragEvents["dragstart"] = prevent;
        duringDragEvents["touchmove mousemove"] = move;
        duringDragEvents["touchend mouseup"] = stop;
        function prevent(e) {
            if (e.stopPropagation) {
                e.stopPropagation();
            }
            if (e.preventDefault) {
                e.preventDefault();
            }
            e.returnValue = false;
        }
        function move(e) {
            if (dragging) {
                if (IE && document.documentMode < 9 && !e.button) {
                    return stop();
                }
                var touches = e.originalEvent.touches;
                var pageX = touches ? touches[0].pageX : e.pageX;
                var pageY = touches ? touches[0].pageY : e.pageY;
                var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
                var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
                if (hasTouch) {
                    prevent(e);
                }
                onmove.apply(element, [dragX, dragY, e]);
            }
        }
        function start(e) {
            var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
            var touches = e.originalEvent.touches;
            if (!rightclick && !dragging) {
                if (onstart.apply(element, arguments) !== false) {
                    dragging = true;
                    maxHeight = $(element).height();
                    maxWidth = $(element).width();
                    offset = $(element).offset();
                    $(doc).bind(duringDragEvents);
                    $(doc.body).addClass("sp-dragging");
                    if (!hasTouch) {
                        move(e);
                    }
                    prevent(e);
                }
            }
        }
        function stop() {
            if (dragging) {
                $(doc).unbind(duringDragEvents);
                $(doc.body).removeClass("sp-dragging");
                onstop.apply(element, arguments);
            }
            dragging = false;
        }
        $(element).bind("touchstart mousedown", start);
    }
    function throttle(func, wait, debounce) {
        var timeout;
        return function () {
            var context = this, args = arguments;
            var throttler = function () {
                timeout = null;
                func.apply(context, args);
            };
            if (debounce) {
                clearTimeout(timeout);
            }
            if (debounce || !timeout) {
                timeout = setTimeout(throttler, wait);
            }
        };
    }
    function log() {
        if (window.console) {
            if (Function.prototype.bind) {
                log = Function.prototype.bind.call(console.log, console);
            } else {
                log = function () {
                    Function.prototype.apply.call(console.log, console, arguments);
                };
            }
            log.apply(this, arguments);
        }
    }
    var dataID = "spectrum.id";
    $.fn.spectrum = function (opts, extra) {
        if (typeof opts == "string") {
            var returnValue = this;
            var args = Array.prototype.slice.call(arguments, 1);
            this.each(function () {
                var spect = spectrums[$(this).data(dataID)];
                if (spect) {
                    var method = spect[opts];
                    if (!method) {
                        throw new Error("Spectrum: no such method: '" + opts + "'");
                    }
                    if (opts == "get") {
                        returnValue = spect.get();
                    } else {
                        if (opts == "container") {
                            returnValue = spect.container;
                        } else {
                            if (opts == "option") {
                                returnValue = spect.option.apply(spect, args);
                            } else {
                                if (opts == "destroy") {
                                    spect.destroy();
                                    $(this).removeData(dataID);
                                } else {
                                    method.apply(spect, args);
                                }
                            }
                        }
                    }
                }
            });
            return returnValue;
        }
        return this.spectrum("destroy").each(function () {
            var spect = spectrum(this, opts);
            $(this).data(dataID, spect.id);
        });
    };
    $.fn.spectrum.load = true;
    $.fn.spectrum.loadOpts = {};
    $.fn.spectrum.draggable = draggable;
    $.fn.spectrum.defaults = defaultOpts;
    $.spectrum = {};
    $.spectrum.localization = {};
    $.spectrum.palettes = {};
    $.fn.spectrum.processNativeColorInputs = function () {
        if (!inputTypeColorSupport) {
            $("input[type=color]").spectrum({preferredFormat:"hex6"});
        }
    };
    (function () {
        var trimLeft = /^[\s,#]+/, trimRight = /\s+$/, tinyCounter = 0, math = Math, mathRound = math.round, mathMin = math.min, mathMax = math.max, mathRandom = math.random;
        function tinycolor(color, opts) {
            color = (color) ? color : "";
            opts = opts || {};
            if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
                return color;
            }
            var rgb = inputToRGB(color);
            var r = rgb.r, g = rgb.g, b = rgb.b, a = rgb.a, roundA = mathRound(100 * a) / 100, format = opts.format || rgb.format;
            if (r < 1) {
                r = mathRound(r);
            }
            if (g < 1) {
                g = mathRound(g);
            }
            if (b < 1) {
                b = mathRound(b);
            }
            return {ok:rgb.ok, format:format, _tc_id:tinyCounter++, alpha:a, getAlpha:function () {
                return a;
            }, setAlpha:function (value) {
                a = boundAlpha(value);
                roundA = mathRound(100 * a) / 100;
            }, toHsv:function () {
                var hsv = rgbToHsv(r, g, b);
                return {h:hsv.h * 360, s:hsv.s, v:hsv.v, a:a};
            }, toHsvString:function () {
                var hsv = rgbToHsv(r, g, b);
                var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
                return (a == 1) ? "hsv(" + h + ", " + s + "%, " + v + "%)" : "hsva(" + h + ", " + s + "%, " + v + "%, " + roundA + ")";
            }, toHsl:function () {
                var hsl = rgbToHsl(r, g, b);
                return {h:hsl.h * 360, s:hsl.s, l:hsl.l, a:a};
            }, toHslString:function () {
                var hsl = rgbToHsl(r, g, b);
                var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
                return (a == 1) ? "hsl(" + h + ", " + s + "%, " + l + "%)" : "hsla(" + h + ", " + s + "%, " + l + "%, " + roundA + ")";
            }, toHex:function (allow3Char) {
                return rgbToHex(r, g, b, allow3Char);
            }, toHexString:function (allow3Char) {
                return "#" + rgbToHex(r, g, b, allow3Char);
            }, toRgb:function () {
                return {r:mathRound(r), g:mathRound(g), b:mathRound(b), a:a};
            }, toRgbString:function () {
                return (a == 1) ? "rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" : "rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")";
            }, toPercentageRgb:function () {
                return {r:mathRound(bound01(r, 255) * 100) + "%", g:mathRound(bound01(g, 255) * 100) + "%", b:mathRound(bound01(b, 255) * 100) + "%", a:a};
            }, toPercentageRgbString:function () {
                return (a == 1) ? "rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" : "rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")";
            }, toName:function () {
                if (a === 0) {
                    return "transparent";
                }
                return hexNames[rgbToHex(r, g, b, true)] || false;
            }, toFilter:function (secondColor) {
                var hex = rgbToHex(r, g, b);
                var secondHex = hex;
                var alphaHex = Math.round(parseFloat(a) * 255).toString(16);
                var secondAlphaHex = alphaHex;
                var gradientType = opts && opts.gradientType ? "GradientType = 1, " : "";
                if (secondColor) {
                    var s = tinycolor(secondColor);
                    secondHex = s.toHex();
                    secondAlphaHex = Math.round(parseFloat(s.alpha) * 255).toString(16);
                }
                return "progid:DXImageTransform.Microsoft.gradient(" + gradientType + "startColorstr=#" + pad2(alphaHex) + hex + ",endColorstr=#" + pad2(secondAlphaHex) + secondHex + ")";
            }, toString:function (format) {
                var formatSet = !!format;
                format = format || this.format;
                var formattedString = false;
                var hasAlphaAndFormatNotSet = !formatSet && a < 1 && a > 0;
                var formatWithAlpha = hasAlphaAndFormatNotSet && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
                if (format === "rgb") {
                    formattedString = this.toRgbString();
                }
                if (format === "prgb") {
                    formattedString = this.toPercentageRgbString();
                }
                if (format === "hex" || format === "hex6") {
                    formattedString = this.toHexString();
                }
                if (format === "hex3") {
                    formattedString = this.toHexString(true);
                }
                if (format === "name") {
                    formattedString = this.toName();
                }
                if (format === "hsl") {
                    formattedString = this.toHslString();
                }
                if (format === "hsv") {
                    formattedString = this.toHsvString();
                }
                if (formatWithAlpha) {
                    return this.toRgbString();
                }
                return formattedString || this.toHexString();
            }};
        }
        tinycolor.fromRatio = function (color, opts) {
            if (typeof color == "object") {
                var newColor = {};
                for (var i in color) {
                    if (color.hasOwnProperty(i)) {
                        if (i === "a") {
                            newColor[i] = color[i];
                        } else {
                            newColor[i] = convertToPercentage(color[i]);
                        }
                    }
                }
                color = newColor;
            }
            return tinycolor(color, opts);
        };
        function inputToRGB(color) {
            var rgb = {r:0, g:0, b:0};
            var a = 1;
            var ok = false;
            var format = false;
            if (typeof color == "string") {
                color = stringInputToObject(color);
            }
            if (typeof color == "object") {
                if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
                    rgb = rgbToRgb(color.r, color.g, color.b);
                    ok = true;
                    format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
                } else {
                    if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
                        color.s = convertToPercentage(color.s);
                        color.v = convertToPercentage(color.v);
                        rgb = hsvToRgb(color.h, color.s, color.v);
                        ok = true;
                        format = "hsv";
                    } else {
                        if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
                            color.s = convertToPercentage(color.s);
                            color.l = convertToPercentage(color.l);
                            rgb = hslToRgb(color.h, color.s, color.l);
                            ok = true;
                            format = "hsl";
                        }
                    }
                }
                if (color.hasOwnProperty("a")) {
                    a = color.a;
                }
            }
            a = boundAlpha(a);
            return {ok:ok, format:color.format || format, r:mathMin(255, mathMax(rgb.r, 0)), g:mathMin(255, mathMax(rgb.g, 0)), b:mathMin(255, mathMax(rgb.b, 0)), a:a};
        }
        function rgbToRgb(r, g, b) {
            return {r:bound01(r, 255) * 255, g:bound01(g, 255) * 255, b:bound01(b, 255) * 255};
        }
        function rgbToHsl(r, g, b) {
            r = bound01(r, 255);
            g = bound01(g, 255);
            b = bound01(b, 255);
            var max = mathMax(r, g, b), min = mathMin(r, g, b);
            var h, s, l = (max + min) / 2;
            if (max == min) {
                h = s = 0;
            } else {
                var d = max - min;
                s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
                switch (max) {
                  case r:
                    h = (g - b) / d + (g < b ? 6 : 0);
                    break;
                  case g:
                    h = (b - r) / d + 2;
                    break;
                  case b:
                    h = (r - g) / d + 4;
                    break;
                }
                h /= 6;
            }
            return {h:h, s:s, l:l};
        }
        function hslToRgb(h, s, l) {
            var r, g, b;
            h = bound01(h, 360);
            s = bound01(s, 100);
            l = bound01(l, 100);
            function hue2rgb(p, q, t) {
                if (t < 0) {
                    t += 1;
                }
                if (t > 1) {
                    t -= 1;
                }
                if (t < 1 / 6) {
                    return p + (q - p) * 6 * t;
                }
                if (t < 1 / 2) {
                    return q;
                }
                if (t < 2 / 3) {
                    return p + (q - p) * (2 / 3 - t) * 6;
                }
                return p;
            }
            if (s === 0) {
                r = g = b = l;
            } else {
                var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
                var p = 2 * l - q;
                r = hue2rgb(p, q, h + 1 / 3);
                g = hue2rgb(p, q, h);
                b = hue2rgb(p, q, h - 1 / 3);
            }
            return {r:r * 255, g:g * 255, b:b * 255};
        }
        function rgbToHsv(r, g, b) {
            r = bound01(r, 255);
            g = bound01(g, 255);
            b = bound01(b, 255);
            var max = mathMax(r, g, b), min = mathMin(r, g, b);
            var h, s, v = max;
            var d = max - min;
            s = max === 0 ? 0 : d / max;
            if (max == min) {
                h = 0;
            } else {
                switch (max) {
                  case r:
                    h = (g - b) / d + (g < b ? 6 : 0);
                    break;
                  case g:
                    h = (b - r) / d + 2;
                    break;
                  case b:
                    h = (r - g) / d + 4;
                    break;
                }
                h /= 6;
            }
            return {h:h, s:s, v:v};
        }
        function hsvToRgb(h, s, v) {
            h = bound01(h, 360) * 6;
            s = bound01(s, 100);
            v = bound01(v, 100);
            var i = math.floor(h), f = h - i, p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s), mod = i % 6, r = [v, q, p, p, t, v][mod], g = [t, v, v, q, p, p][mod], b = [p, p, t, v, v, q][mod];
            return {r:r * 255, g:g * 255, b:b * 255};
        }
        function rgbToHex(r, g, b, allow3Char) {
            var hex = [pad2(mathRound(r).toString(16)), pad2(mathRound(g).toString(16)), pad2(mathRound(b).toString(16))];
            if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
                return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
            }
            return hex.join("");
        }
        tinycolor.equals = function (color1, color2) {
            if (!color1 || !color2) {
                return false;
            }
            return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
        };
        tinycolor.random = function () {
            return tinycolor.fromRatio({r:mathRandom(), g:mathRandom(), b:mathRandom()});
        };
        tinycolor.desaturate = function (color, amount) {
            amount = (amount === 0) ? 0 : (amount || 10);
            var hsl = tinycolor(color).toHsl();
            hsl.s -= amount / 100;
            hsl.s = clamp01(hsl.s);
            return tinycolor(hsl);
        };
        tinycolor.saturate = function (color, amount) {
            amount = (amount === 0) ? 0 : (amount || 10);
            var hsl = tinycolor(color).toHsl();
            hsl.s += amount / 100;
            hsl.s = clamp01(hsl.s);
            return tinycolor(hsl);
        };
        tinycolor.greyscale = function (color) {
            return tinycolor.desaturate(color, 100);
        };
        tinycolor.lighten = function (color, amount) {
            amount = (amount === 0) ? 0 : (amount || 10);
            var hsl = tinycolor(color).toHsl();
            hsl.l += amount / 100;
            hsl.l = clamp01(hsl.l);
            return tinycolor(hsl);
        };
        tinycolor.darken = function (color, amount) {
            amount = (amount === 0) ? 0 : (amount || 10);
            var hsl = tinycolor(color).toHsl();
            hsl.l -= amount / 100;
            hsl.l = clamp01(hsl.l);
            return tinycolor(hsl);
        };
        tinycolor.complement = function (color) {
            var hsl = tinycolor(color).toHsl();
            hsl.h = (hsl.h + 180) % 360;
            return tinycolor(hsl);
        };
        tinycolor.triad = function (color) {
            var hsl = tinycolor(color).toHsl();
            var h = hsl.h;
            return [tinycolor(color), tinycolor({h:(h + 120) % 360, s:hsl.s, l:hsl.l}), tinycolor({h:(h + 240) % 360, s:hsl.s, l:hsl.l})];
        };
        tinycolor.tetrad = function (color) {
            var hsl = tinycolor(color).toHsl();
            var h = hsl.h;
            return [tinycolor(color), tinycolor({h:(h + 90) % 360, s:hsl.s, l:hsl.l}), tinycolor({h:(h + 180) % 360, s:hsl.s, l:hsl.l}), tinycolor({h:(h + 270) % 360, s:hsl.s, l:hsl.l})];
        };
        tinycolor.splitcomplement = function (color) {
            var hsl = tinycolor(color).toHsl();
            var h = hsl.h;
            return [tinycolor(color), tinycolor({h:(h + 72) % 360, s:hsl.s, l:hsl.l}), tinycolor({h:(h + 216) % 360, s:hsl.s, l:hsl.l})];
        };
        tinycolor.analogous = function (color, results, slices) {
            results = results || 6;
            slices = slices || 30;
            var hsl = tinycolor(color).toHsl();
            var part = 360 / slices;
            var ret = [tinycolor(color)];
            for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
                hsl.h = (hsl.h + part) % 360;
                ret.push(tinycolor(hsl));
            }
            return ret;
        };
        tinycolor.monochromatic = function (color, results) {
            results = results || 6;
            var hsv = tinycolor(color).toHsv();
            var h = hsv.h, s = hsv.s, v = hsv.v;
            var ret = [];
            var modification = 1 / results;
            while (results--) {
                ret.push(tinycolor({h:h, s:s, v:v}));
                v = (v + modification) % 1;
            }
            return ret;
        };
        tinycolor.readability = function (color1, color2) {
            var a = tinycolor(color1).toRgb();
            var b = tinycolor(color2).toRgb();
            var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
            var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
            var colorDiff = (Math.max(a.r, b.r) - Math.min(a.r, b.r) + Math.max(a.g, b.g) - Math.min(a.g, b.g) + Math.max(a.b, b.b) - Math.min(a.b, b.b));
            return {brightness:Math.abs(brightnessA - brightnessB), color:colorDiff};
        };
        tinycolor.readable = function (color1, color2) {
            var readability = tinycolor.readability(color1, color2);
            return readability.brightness > 125 && readability.color > 500;
        };
        tinycolor.mostReadable = function (baseColor, colorList) {
            var bestColor = null;
            var bestScore = 0;
            var bestIsReadable = false;
            for (var i = 0; i < colorList.length; i++) {
                var readability = tinycolor.readability(baseColor, colorList[i]);
                var readable = readability.brightness > 125 && readability.color > 500;
                var score = 3 * (readability.brightness / 125) + (readability.color / 500);
                if ((readable && !bestIsReadable) || (readable && bestIsReadable && score > bestScore) || ((!readable) && (!bestIsReadable) && score > bestScore)) {
                    bestIsReadable = readable;
                    bestScore = score;
                    bestColor = tinycolor(colorList[i]);
                }
            }
            return bestColor;
        };
        var names = tinycolor.names = {aliceblue:"f0f8ff", antiquewhite:"faebd7", aqua:"0ff", aquamarine:"7fffd4", azure:"f0ffff", beige:"f5f5dc", bisque:"ffe4c4", black:"000", blanchedalmond:"ffebcd", blue:"00f", blueviolet:"8a2be2", brown:"a52a2a", burlywood:"deb887", burntsienna:"ea7e5d", cadetblue:"5f9ea0", chartreuse:"7fff00", chocolate:"d2691e", coral:"ff7f50", cornflowerblue:"6495ed", cornsilk:"fff8dc", crimson:"dc143c", cyan:"0ff", darkblue:"00008b", darkcyan:"008b8b", darkgoldenrod:"b8860b", darkgray:"a9a9a9", darkgreen:"006400", darkgrey:"a9a9a9", darkkhaki:"bdb76b", darkmagenta:"8b008b", darkolivegreen:"556b2f", darkorange:"ff8c00", darkorchid:"9932cc", darkred:"8b0000", darksalmon:"e9967a", darkseagreen:"8fbc8f", darkslateblue:"483d8b", darkslategray:"2f4f4f", darkslategrey:"2f4f4f", darkturquoise:"00ced1", darkviolet:"9400d3", deeppink:"ff1493", deepskyblue:"00bfff", dimgray:"696969", dimgrey:"696969", dodgerblue:"1e90ff", firebrick:"b22222", floralwhite:"fffaf0", forestgreen:"228b22", fuchsia:"f0f", gainsboro:"dcdcdc", ghostwhite:"f8f8ff", gold:"ffd700", goldenrod:"daa520", gray:"808080", green:"008000", greenyellow:"adff2f", grey:"808080", honeydew:"f0fff0", hotpink:"ff69b4", indianred:"cd5c5c", indigo:"4b0082", ivory:"fffff0", khaki:"f0e68c", lavender:"e6e6fa", lavenderblush:"fff0f5", lawngreen:"7cfc00", lemonchiffon:"fffacd", lightblue:"add8e6", lightcoral:"f08080", lightcyan:"e0ffff", lightgoldenrodyellow:"fafad2", lightgray:"d3d3d3", lightgreen:"90ee90", lightgrey:"d3d3d3", lightpink:"ffb6c1", lightsalmon:"ffa07a", lightseagreen:"20b2aa", lightskyblue:"87cefa", lightslategray:"789", lightslategrey:"789", lightsteelblue:"b0c4de", lightyellow:"ffffe0", lime:"0f0", limegreen:"32cd32", linen:"faf0e6", magenta:"f0f", maroon:"800000", mediumaquamarine:"66cdaa", mediumblue:"0000cd", mediumorchid:"ba55d3", mediumpurple:"9370db", mediumseagreen:"3cb371", mediumslateblue:"7b68ee", mediumspringgreen:"00fa9a", mediumturquoise:"48d1cc", mediumvioletred:"c71585", midnightblue:"191970", mintcream:"f5fffa", mistyrose:"ffe4e1", moccasin:"ffe4b5", navajowhite:"ffdead", navy:"000080", oldlace:"fdf5e6", olive:"808000", olivedrab:"6b8e23", orange:"ffa500", orangered:"ff4500", orchid:"da70d6", palegoldenrod:"eee8aa", palegreen:"98fb98", paleturquoise:"afeeee", palevioletred:"db7093", papayawhip:"ffefd5", peachpuff:"ffdab9", peru:"cd853f", pink:"ffc0cb", plum:"dda0dd", powderblue:"b0e0e6", purple:"800080", red:"f00", rosybrown:"bc8f8f", royalblue:"4169e1", saddlebrown:"8b4513", salmon:"fa8072", sandybrown:"f4a460", seagreen:"2e8b57", seashell:"fff5ee", sienna:"a0522d", silver:"c0c0c0", skyblue:"87ceeb", slateblue:"6a5acd", slategray:"708090", slategrey:"708090", snow:"fffafa", springgreen:"00ff7f", steelblue:"4682b4", tan:"d2b48c", teal:"008080", thistle:"d8bfd8", tomato:"ff6347", turquoise:"40e0d0", violet:"ee82ee", wheat:"f5deb3", white:"fff", whitesmoke:"f5f5f5", yellow:"ff0", yellowgreen:"9acd32"};
        var hexNames = tinycolor.hexNames = flip(names);
        function flip(o) {
            var flipped = {};
            for (var i in o) {
                if (o.hasOwnProperty(i)) {
                    flipped[o[i]] = i;
                }
            }
            return flipped;
        }
        function boundAlpha(a) {
            a = parseFloat(a);
            if (isNaN(a) || a < 0 || a > 1) {
                a = 1;
            }
            return a;
        }
        function bound01(n, max) {
            if (isOnePointZero(n)) {
                n = "100%";
            }
            var processPercent = isPercentage(n);
            n = mathMin(max, mathMax(0, parseFloat(n)));
            if (processPercent) {
                n = parseInt(n * max, 10) / 100;
            }
            if ((math.abs(n - max) < 0.000001)) {
                return 1;
            }
            return (n % max) / parseFloat(max);
        }
        function clamp01(val) {
            return mathMin(1, mathMax(0, val));
        }
        function parseHex(val) {
            return parseInt(val, 16);
        }
        function isOnePointZero(n) {
            return typeof n == "string" && n.indexOf(".") != -1 && parseFloat(n) === 1;
        }
        function isPercentage(n) {
            return typeof n === "string" && n.indexOf("%") != -1;
        }
        function pad2(c) {
            return c.length == 1 ? "0" + c : "" + c;
        }
        function convertToPercentage(n) {
            if (n <= 1) {
                n = (n * 100) + "%";
            }
            return n;
        }
        var matchers = (function () {
            var CSS_INTEGER = "[-\\+]?\\d+%?";
            var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
            var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
            var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
            var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
            return {rgb:new RegExp("rgb" + PERMISSIVE_MATCH3), rgba:new RegExp("rgba" + PERMISSIVE_MATCH4), hsl:new RegExp("hsl" + PERMISSIVE_MATCH3), hsla:new RegExp("hsla" + PERMISSIVE_MATCH4), hsv:new RegExp("hsv" + PERMISSIVE_MATCH3), hex3:/^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, hex6:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/};
        })();
        function stringInputToObject(color) {
            color = color.replace(trimLeft, "").replace(trimRight, "").toLowerCase();
            var named = false;
            if (names[color]) {
                color = names[color];
                named = true;
            } else {
                if (color == "transparent") {
                    return {r:0, g:0, b:0, a:0, format:"name"};
                }
            }
            var match;
            if ((match = matchers.rgb.exec(color))) {
                return {r:match[1], g:match[2], b:match[3]};
            }
            if ((match = matchers.rgba.exec(color))) {
                return {r:match[1], g:match[2], b:match[3], a:match[4]};
            }
            if ((match = matchers.hsl.exec(color))) {
                return {h:match[1], s:match[2], l:match[3]};
            }
            if ((match = matchers.hsla.exec(color))) {
                return {h:match[1], s:match[2], l:match[3], a:match[4]};
            }
            if ((match = matchers.hsv.exec(color))) {
                return {h:match[1], s:match[2], v:match[3]};
            }
            if ((match = matchers.hex6.exec(color))) {
                return {r:parseHex(match[1]), g:parseHex(match[2]), b:parseHex(match[3]), format:named ? "name" : "hex"};
            }
            if ((match = matchers.hex3.exec(color))) {
                return {r:parseHex(match[1] + "" + match[1]), g:parseHex(match[2] + "" + match[2]), b:parseHex(match[3] + "" + match[3]), format:named ? "name" : "hex"};
            }
            return false;
        }
        window.tinycolor = tinycolor;
    })();
    $(function () {
        if ($.fn.spectrum.load) {
            $.fn.spectrum.processNativeColorInputs();
        }
    });
})(window, jQuery);
(function () {
    var PALETTES = {"#sixteen":[["#000000", "#000084", "#0000ff", "#840000"], ["#840084", "#008200", "#ff0000", "#008284"], ["#ff00ff", "#848200", "#848284", "#00ff00"], ["#ffa600", "#00ffff", "#c6c3c6", "#ffff00"], ["#ffffff"]], "#websafe":[["#000", "#300", "#600", "#900", "#c00", "#f00"], ["#003", "#303", "#603", "#903", "#c03", "#f03"], ["#006", "#306", "#606", "#906", "#c06", "#f06"], ["#009", "#309", "#609", "#909", "#c09", "#f09"], ["#00c", "#30c", "#60c", "#90c", "#c0c", "#f0c"], ["#00f", "#30f", "#60f", "#90f", "#c0f", "#f0f"], ["#030", "#330", "#630", "#930", "#c30", "#f30"], ["#033", "#333", "#633", "#933", "#c33", "#f33"], ["#036", "#336", "#636", "#936", "#c36", "#f36"], ["#039", "#339", "#639", "#939", "#c39", "#f39"], ["#03c", "#33c", "#63c", "#93c", "#c3c", "#f3c"], ["#03f", "#33f", "#63f", "#93f", "#c3f", "#f3f"], ["#060", "#360", "#660", "#960", "#c60", "#f60"], ["#063", "#363", "#663", "#963", "#c63", "#f63"], ["#066", "#366", "#666", "#966", "#c66", "#f66"], ["#069", "#369", "#669", "#969", "#c69", "#f69"], ["#06c", "#36c", "#66c", "#96c", "#c6c", "#f6c"], ["#06f", "#36f", "#66f", "#96f", "#c6f", "#f6f"], ["#090", "#390", "#690", "#990", "#c90", "#f90"], ["#093", "#393", "#693", "#993", "#c93", "#f93"], ["#096", "#396", "#696", "#996", "#c96", "#f96"], ["#099", "#399", "#699", "#999", "#c99", "#f99"], ["#09c", "#39c", "#69c", "#99c", "#c9c", "#f9c"], ["#09f", "#39f", "#69f", "#99f", "#c9f", "#f9f"], ["#0c0", "#3c0", "#6c0", "#9c0", "#cc0", "#fc0"], ["#0c3", "#3c3", "#6c3", "#9c3", "#cc3", "#fc3"], ["#0c6", "#3c6", "#6c6", "#9c6", "#cc6", "#fc6"], ["#0c9", "#3c9", "#6c9", "#9c9", "#cc9", "#fc9"], ["#0cc", "#3cc", "#6cc", "#9cc", "#ccc", "#fcc"], ["#0cf", "#3cf", "#6cf", "#9cf", "#ccf", "#fcf"], ["#0f0", "#3f0", "#6f0", "#9f0", "#cf0", "#ff0"], ["#0f3", "#3f3", "#6f3", "#9f3", "#cf3", "#ff3"], ["#0f6", "#3f6", "#6f6", "#9f6", "#cf6", "#ff6"], ["#0f9", "#3f9", "#6f9", "#9f9", "#cf9", "#ff9"], ["#0fc", "#3fc", "#6fc", "#9fc", "#cfc", "#ffc"], ["#0ff", "#3ff", "#6ff", "#9ff", "#cff", "#fff"]], "#named":[["White", "Ivory", "Snow", "LightYellow", "MintCream", "Azure", "FloralWhite", "Honeydew", "GhostWhite", "Seashell", "Cornsilk", "AliceBlue", "LemonChiffon", "LightCyan"], ["OldLace", "LightGoldenrodYellow", "LavenderBlush", "WhiteSmoke", "Beige", "Linen", "PapayaWhip", "BlanchedAlmond", "AntiqueWhite", "MistyRose", "Bisque", "Lavender", "Moccasin", "PaleGoldenrod"], ["NavajoWhite", "Yellow", "PeachPuff", "Wheat", "Khaki", "Gainsboro", "PaleTurquoise", "Pink", "Aquamarine", "LightGray", "PowderBlue", "PaleGreen", "GreenYellow", "LightPink"], ["LightBlue", "Gold", "Thistle", "LightGreen", "LightSteelBlue", "Silver", "LightSkyBlue", "BurlyWood", "SkyBlue", "Chartreuse", "Plum", "LawnGreen", "Tan", "LightSalmon"], ["SandyBrown", "Cyan", "Aqua", "DarkKhaki", "Violet", "Turquoise", "Orange", "YellowGreen", "DarkSalmon", "MediumAquamarine", "DarkSeaGreen", "DarkGray", "MediumTurquoise", "Goldenrod"], ["MediumSpringGreen", "SpringGreen", "Salmon", "LightCoral", "Coral", "DarkOrange", "HotPink", "RosyBrown", "Orchid", "Lime", "PaleVioletRed", "Peru", "DarkTurquoise", "CornflowerBlue"], ["Tomato", "DeepSkyBlue", "LimeGreen", "CadetBlue", "MediumSeaGreen", "DarkGoldenrod", "MediumPurple", "LightSeaGreen", "LightSlateGray", "MediumOrchid", "Gray", "Chocolate", "IndianRed", "SlateGray"], ["MediumSlateBlue", "DodgerBlue", "OliveDrab", "SteelBlue", "OrangeRed", "Olive", "SlateBlue", "RoyalBlue", "Magenta", "Fuchsia", "SeaGreen", "DimGray", "DeepPink", "Sienna"], ["DarkOrchid", "DarkCyan", "ForestGreen", "DarkOliveGreen", "BlueViolet", "Teal", "MediumVioletRed", "Crimson", "SaddleBrown", "Brown", "FireBrick", "Red", "Green", "DarkSlateBlue"], ["DarkSlateGray", "DarkViolet", "DarkGreen", "DarkMagenta", "Purple", "DarkRed", "Maroon", "Indigo", "MidnightBlue", "Blue", "MediumBlue", "DarkBlue", "Navy", "Black"]]};
    dorado.widget.ColorPickerSupport = $class({$className:"dorado.widget.ColorPickerSupport", ATTRIBUTES:{color:{}, showInput:{spectrumAttr:true}, showInitial:{spectrumAttr:true}, allowEmpty:{}, showAlpha:{spectrumAttr:true}, disabled:{spectrumAttr:true}, showPalette:{spectrumAttr:true}, showPaletteOnly:{spectrumAttr:true}, showButtons:{defaultValue:true, writeBeforeReady:true}, preferredFormat:{writeBeforeReady:true}, palette:{defaultValue:PALETTES["#sixteen"], writeBeforeReady:true}}});
    dorado.widget.ColorPicker = $extend([dorado.widget.Control, dorado.widget.ColorPickerSupport], {$className:"dorado.widget.ColorPicker", focusable:true, ATTRIBUTES:{className:{defaultValue:"d-color-picker"}, width:{independent:true}, height:{independent:true}, color:{skipRefresh:true, getter:function () {
        if (this._spectrum) {
            var rudeColor = this._spectrum.spectrum("get");
            return rudeColor.toString(this._preferredFormat);
        } else {
            return this._color;
        }
    }, setter:function (color) {
        if (this._spectrum) {
            this._spectrum.spectrum("set", color);
        } else {
            this._color = color;
        }
    }}}, EVENTS:{onColorChange:{}, onCursorMove:{}}, doSet:function (attr, value, skipUnknownAttribute, lockWritingTimes) {
        $invokeSuper.call(this, [attr, value, skipUnknownAttribute, lockWritingTimes]);
        if (this._spectrum) {
            var def = this.ATTRIBUTES[attr];
            if (def.spectrumAttr) {
                this._spectrum.spectrum("option", attr, value);
            }
        }
    }, getBaseSpectrumOption:function () {
        return {flat:true};
    }, createDom:function () {
        var colorPicker = this, inputDom = $DomUtils.xCreate({tagName:"INPUT"});
        $DomUtils.getInvisibleContainer().appendChild(inputDom);
        colorPicker._spectrum = jQuery(inputDom);
        var options = colorPicker.getBaseSpectrumOption();
        var palette = colorPicker._palette;
        if (palette && palette.length == 1 && PALETTES[palette[0]]) {
            palette = PALETTES[palette[0]];
        }
        var $container = colorPicker._spectrum.spectrum(dorado.Object.apply(options, {color:colorPicker._color, showInput:colorPicker._showInput, showInitial:colorPicker._showInitial, allowEmpty:colorPicker._allowEmpty, showAlpha:colorPicker._showAlpha, disabled:colorPicker._disabled, showPalette:colorPicker._showPalette, showPaletteOnly:colorPicker._showPaletteOnly, showButtons:colorPicker._showButtons, preferredFormat:colorPicker._preferredFormat, palette:palette, show:function () {
            setTimeout(function () {
                $container.bringToFront();
            }, 0);
        }, move:function (rudeColor) {
            colorPicker.onCursorMove(rudeColor.toString(colorPicker._preferredFormat));
        }, change:function (rudeColor) {
            colorPicker.onColorChange(rudeColor.toString(colorPicker._preferredFormat));
        }})).spectrum("container");
        var dom = inputDom.nextSibling;
        $DomUtils.getInvisibleContainer().removeChild(inputDom);
        $container[0].doradoUniqueId = this._uniqueId;
        colorPicker._originalButtonCancel = $container.find(".sp-cancel");
        colorPicker._originalButtonOk = $container.find(".sp-choose");
        if (this._showButtons) {
            buttonCancel = new dorado.widget.Button({exClassName:"button-cancel", caption:$resource("dorado.baseWidget.MessageBoxButtonCancel"), renderOn:colorPicker._originalButtonCancel[0], onClick:function () {
                colorPicker._originalButtonCancel.click();
            }});
            colorPicker.registerInnerControl(buttonCancel);
            buttonCancel.render();
            buttonOk = new dorado.widget.Button({exClassName:"button-ok", ui:"highlight", caption:$resource("dorado.baseWidget.MessageBoxButtonOK"), renderOn:colorPicker._originalButtonOk[0], onClick:function () {
                colorPicker._originalButtonOk.click();
            }});
            colorPicker.registerInnerControl(buttonOk);
            buttonOk.render();
        }
        return dom;
    }, onCursorMove:function (color) {
        this.fireEvent("onCursorMove", this, {color:color});
    }, onColorChange:function (color) {
        this.fireEvent("onColorChange", this, {color:color});
    }});
    dorado.widget.ColorEditor = $extend([dorado.widget.ColorPicker, dorado.widget.AbstractDataEditor], {$className:"dorado.widget.ColorEditor", _triggerChanged:true, ATTRIBUTES:{className:{defaultValue:"d-color-editor"}, value:{skipRefresh:true, path:"color"}}, EVENTS:{onValueChange:{}}, getBaseSpectrumOption:function () {
        return {flat:false};
    }, createDom:function () {
        var dom = $invokeSuper.call(this, arguments);
        this._spectrum.spectrum("container").shadow({mode:"sides"});
        return dom;
    }, refreshDom:function (dom) {
        dorado.widget.AbstractDataEditor.prototype.refreshDom.call(this, dom);
        var colorEditor = this;
        if (colorEditor._dataSet) {
            if (colorEditor._property) {
                var bindingInfo = colorEditor._bindingInfo;
                if (bindingInfo.entity instanceof dorado.Entity) {
                    var color = bindingInfo.entity.get(colorEditor._property);
                    colorEditor.set("color", color);
                }
            }
        }
    }, onColorChange:function (color) {
        $invokeSuper.call(this, arguments);
        this.post();
    }, doOnBlur:function () {
        this._originalButtonCancel.click();
    }});
})();

